package com.tiancheng.trade.payment.channel.fudian.util;

import cn.hutool.json.JSONUtil;
import com.tiancheng.trade.commom.core.utils.MD5Util;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 富滇签名工具
 *
 * @author kellen
 * @date 2024/4/10
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public final class FudianSignUtil {

    // 富滇签名key
    private static String key = "kmnt192006250b4c09247ec02edce69f6a2d";

    /**
     * 根据参数获取签名
     *
     * @param timeStamp
     * @param params
     * @return
     */
    public static String createSign(String timeStamp, SortedMap<String, Object> params) {
        log.info("富滇签名时间戳：" + timeStamp);
        log.info("富滇签名参数：" + JSONUtil.toJsonStr(params));
        String plain = generateSignPlain(params).toString();
        String md5value = plain + "&key=" + key;
        //排序后的参数MD5加密
        String sign = MD5Util.MD5Encode(md5value, "UTF-8");
        log.info("富滇签名1：" + sign);
        sign = sign + timeStamp;
        sign = MD5Util.MD5Encode(sign, "UTF-8");
        log.info("富滇签名2：" + sign);
        return sign;
    }

    /**
     * 按照key值字典顺序，并用&拼接
     *
     * @param params
     * @return
     */
    private static StringBuilder generateSignPlain(SortedMap<String, Object> params) {
        StringBuilder plain = new StringBuilder();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (entry.getValue() instanceof List) {
                List<Map<String, Object>> list = (List<Map<String, Object>>) entry.getValue();
                if (list != null && list.size() > 0) {
                    plain.append(entry.getKey() + "=[");
                    for (int i = 0; i < list.size(); i++) {
                        plain.append("{").append(generateSignPlain(new TreeMap<>(list.get(i))));
                        plain.append(i == list.size() - 1 ? "}" : "}&");
                    }
                    plain.append("]&");
                }
            } else if (entry.getValue() instanceof Map) {
                Map<String, Object> map = (Map<String, Object>) entry.getValue();
                if (map != null && map.size() > 0) {
                    plain.append(entry.getKey() + "=").append("{").append(generateSignPlain(new TreeMap<>(map))).append("}&");
                }
            } else {
                plain.append(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        return plain.length() > 0 ? plain.deleteCharAt(plain.length() - 1) : new StringBuilder();
    }
}
